use ezk_g711::{alaw, mulaw};
use ezk_g722::G722Decoder;

pub struct AudioEncoder {
    pub(crate) codec_name: String,
    pub(crate) sample_rate: u32,
    pub(crate) channels: u32,
}

impl AudioEncoder {
    pub fn new(codec_name: &str, sample_rate: u32, channels: u32) -> Self {
        log::info!("创建音频编码器: {}, {}Hz, {} 声道", codec_name, sample_rate, channels);
        Self { codec_name: codec_name.to_string(), sample_rate, channels }
    }
    pub fn encode(&self, samples: &[i16]) -> Vec<u8> {
        let expected_frame_size = (self.sample_rate * 20 / 1000) as usize;
        if samples.len() != expected_frame_size { log::warn!("音频帧大小不匹配: 期望 {}, 实际 {}", expected_frame_size, samples.len()); }
        match self.codec_name.as_str() {
            "PCMU" => samples.iter().map(|&s| mulaw::encode(s)).collect(),
            "PCMA" => samples.iter().map(|&s| alaw::encode(s)).collect(),
            "G722" => { log::warn!("G.722编码暂未实现，使用PCMU替代"); samples.iter().map(|&s| mulaw::encode(s)).collect() }
            _ => { log::warn!("不支持的编解码器: {}，使用PCMU替代", self.codec_name); samples.iter().map(|&s| mulaw::encode(s)).collect() }
        }
    }
}

pub struct AudioDecoder {
    pub(crate) g722_decoder: Option<G722Decoder>,
    pub(crate) codec_name: String,
}

impl AudioDecoder {
    pub fn new(codec_name: &str, sample_rate: u32) -> Self {
        log::info!("创建音频解码器: {}, {}Hz", codec_name, sample_rate);
        let g722_decoder = if codec_name == "G722" { Some(G722Decoder::new()) } else { None };
        Self { g722_decoder, codec_name: codec_name.to_string() }
    }
    pub fn decode(&mut self, encoded_data: &[u8]) -> Vec<i16> {
        match self.codec_name.as_str() {
            "PCMU" => encoded_data.iter().map(|&b| mulaw::decode(b)).collect(),
            "PCMA" => encoded_data.iter().map(|&b| alaw::decode(b)).collect(),
            "G722" => { if let Some(ref mut dec) = self.g722_decoder { let mut out = Vec::new(); dec.decode(encoded_data, &mut out); out } else { Vec::new() } }
            _ => { log::warn!("不支持的编解码器: {}", self.codec_name); Vec::new() }
        }
    }
}


